#include	"../core/mongoose.h"
#include	"../utils/logger.h"
#include	"api_def.h"
#include	<ctime>

static int Api_HttpHeader(lua_State * pL) {
	size_t nLen = 0;
	const char * sData = lua_tolstring(pL, 1, &nLen);

	std::string sRet;
	lua_getglobal(pL, "_HEADER");
	if (lua_isnil(pL, -1)) {
		sRet.append(sData);
	} else {
		size_t nOld = 0;
		const char * sOld = lua_tolstring(pL, -1, &nOld);
		sRet.append(sOld, nOld);
		sRet.append("\r\n");
		sRet.append(sData, nLen);
	}
	lua_pop(pL, 1);

	lua_pushlstring(pL, sRet.data(), sRet.size());
	lua_setglobal(pL, "_HEADER");
	return 0;
}

static int Api_HttpEcho(lua_State * pL) {
	size_t nLen = 0;
	const char * sData = lua_tolstring(pL, 1, &nLen);

	std::string sRet;
	lua_getglobal(pL, "_CONTENT");
	if (lua_isnil(pL, -1)) {
		sRet.append(sData);
	} else {
		size_t nOld = 0;
		const char * sOld = lua_tolstring(pL, -1, &nOld);
		sRet.append(sOld, nOld);
		sRet.append(sData, nLen);
	}
	lua_pop(pL, 1);

	lua_pushlstring(pL, sRet.data(), sRet.size());
	lua_setglobal(pL, "_CONTENT");
	return 0;
}

static int Api_HttpFlush(lua_State * pL) {
	std::string sHeader, sContent;
	size_t nLen = 0;
	mg_connection * pConn = nullptr;

	lua_getglobal(pL, "_CONN");
	if (lua_isnil(pL, -1)) {
		LOG_ERR("Missing connection data for redirect");
		return 0;
	} else {
		pConn = (mg_connection *)lua_topointer(pL, -1);
	}	 

	lua_getglobal(pL, "_HEADER");
	if (!lua_isnil(pL, -1)) {
		const char * sH = lua_tolstring(pL, -1, &nLen);
		sHeader = std::string(sH, nLen);
	}
	lua_pop(pL, 1);
	
	lua_getglobal(pL, "_CONTENT");
	if (!lua_isnil(pL, -1)) {
		const char * sC = lua_tolstring(pL, -1, &nLen);
		sContent = std::string(sC, nLen);
	}
	lua_pop(pL, 1);

	if (sHeader.empty()) sHeader = "Content-type:text/html";

	mg_send_head(pConn, 200, sContent.length(), sHeader.c_str());
	mg_send(pConn, sContent.c_str(), sContent.length());

	lua_pushnil(pL);
	lua_setglobal(pL, "_HEADER");
	lua_pushnil(pL);
	lua_setglobal(pL, "_CONTENT");
	return 0;
}

static int Api_HttpRedirect(lua_State * pL) {
	mg_str iUrl, iExtra;
	iUrl.p = lua_tolstring(pL, 1, &iUrl.len);
	iExtra.len = 0;

	lua_getglobal(pL, "_CONN");
	if (lua_isnil(pL, -1)) {
		LOG_ERR("Missing connection data for redirect");
		return 0;
	}

	mg_connection * pConn = (mg_connection *)lua_topointer(pL, -1);
	mg_http_send_redirect(pConn, 302, iUrl, iExtra);
	pConn->flags |= MG_F_SEND_AND_CLOSE;

	lua_pop(pL, 1);
	lua_pushboolean(pL, true);
	lua_setglobal(pL, "_REDIRECT");
	luaL_error(pL, "redirect");
	return 0;
}

static int Api_HttpGMTime(lua_State * pL) {
	time_t nCur = (time_t)lua_tointeger(pL, 1);
	auto pGMT = gmtime(&nCur);

	char pBuf[64] = { 0 };
	strftime(pBuf, 32, "%a, %d %b %Y %H:%M:%S GMT", pGMT);
	lua_pushstring(pL, pBuf);
	return 1;
}

void RegisterApi_Http(lua_State * pL) {
	REGAPI(pL, Api_HttpHeader, "header");
	REGAPI(pL, Api_HttpEcho, "echo");
	REGAPI(pL, Api_HttpFlush, "flush");
	REGAPI(pL, Api_HttpRedirect, "redirect");
	REGAPI(pL, Api_HttpGMTime, "time");
}